package com.tanhua.server.service;

import com.tanhua.autoconfig.template.OssTemplate;
import com.tanhua.commons.constant.Constants;
import com.tanhua.commons.exception.TanHuaException;
import com.tanhua.dubbo.api.db.UserInfoApi;
import com.tanhua.dubbo.api.mongo.PeachblossomApi;
import com.tanhua.model.db.UserInfo;
import com.tanhua.model.mongo.Voice;
import com.tanhua.model.vo.ErrorResult;
import com.tanhua.model.vo.VoiceVo;
import com.tanhua.server.interceptor.UserHolder;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * 语音发送业务层
 */
@Service
@Slf4j
public class PeachblossomService {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @DubboReference
    private PeachblossomApi peachblossomApi;

    @Autowired
    private OssTemplate ossTemplate;//阿里云api

    @DubboReference
    private UserInfoApi userInfoApi;

    /**
     * 发送语音
     * @author LittleLynn
     */
    public void sendVoice(MultipartFile soundFile) throws IOException {
        //获取用户ID
        Long userId = UserHolder.getUserId();
        /**
         * 构造语音对象,将语音记录存入mongo数据库
         */
        Voice voice = new Voice();
        //调用阿里云存储语音返回语音地址
        String url = ossTemplate.upload(soundFile.getOriginalFilename(), soundFile.getInputStream());
        voice.setSoundUrl(url);
        UserInfo userInfo = userInfoApi.getUserInfo(userId);
        voice.setGender(userInfo.getGender());
        voice.setUserId(userId);
        voice.setCreated(new Date().getTime());
        //设置大Key
        String key = Constants.VOICE;
        //设置小Key
        String hashKey = userId.toString();
        //设置发送语音次数
        String num = Constants.SEND_VOICE_NUM.toString();
        /**
         * 将发送语音的次数存入Redis数据库
         */
        //判断Redis中是否有值
        Boolean hasKey = stringRedisTemplate.opsForHash().hasKey(key, hashKey);
        //假如没有值,保存语音记录,保存语音次数,设置Redis时效.
        if(!hasKey){
            peachblossomApi.add(voice);
            stringRedisTemplate.opsForHash().put(key,hashKey,num);
            stringRedisTemplate.opsForHash().increment(key,hashKey,1);
            //计算当前时间离次日凌晨的时间差
            LocalDateTime midnight = LocalDateTime.now().plusDays(1).withHour(0).withMinute(0).withSecond(0).withNano(0);
            long seconds = ChronoUnit.SECONDS.between(LocalDateTime.now(), midnight);
            //设置失效时间
            stringRedisTemplate.expire(hashKey,seconds, TimeUnit.SECONDS);
        }else {
            //假如有值并且小于3次,保存语音记录,保存语音次数.
            String userNum = stringRedisTemplate.opsForHash().get(key,hashKey).toString();
            int value = Integer.parseInt(userNum);
            if(value < 3){
                peachblossomApi.add(voice);
                stringRedisTemplate.opsForHash().increment(key,hashKey,1);
            }else {
                //值大于3次,给出温馨提示.
                throw new TanHuaException("今天发送语音次数已用完,请明天再来哦!!!");
            }
        }

    }

    /**
     * 接收语音
     *
     * @return
     */
    public VoiceVo receiveVoice() {
        //获得当前用户id
        Long userId = UserHolder.getUserId();
        //定义接收语音次数,默认3次
        Integer receiveVoiceNum = 3;
        //定义redis中接收语音的key
        String timeKey = Constants.RECEIVE_VOICE_TIME + userId;
        //定义redis中存储接收次数的key
        String countKey = Constants.RECEIVE_VOICE;
        //从redis中获得剩余接收语音次数
        String hashKey = Constants.RECEIVE_VOICE_NUM + userId;
        String receiveVoiceNumStr = (String) stringRedisTemplate.opsForHash().get(countKey, hashKey);
        if (StringUtils.isNotEmpty(receiveVoiceNumStr)) {
            //使用redis中的次数
            receiveVoiceNum = Integer.valueOf(receiveVoiceNumStr);
        }
        if (receiveVoiceNum > 0) {  //还有次数则执行
            //查询用户信息,获得用户的性别
            UserInfo userInfo = userInfoApi.getUserInfo(userId);
            String gender = userInfo.getGender();

            //获取redis中已读用户语音的创建时间
            Set<String> voiceDate = stringRedisTemplate.opsForSet().members(timeKey);

            //调用api获得排除后的语音信息（排除相同性别用户和已读的语音）
            Voice voice = peachblossomApi.findVoiceByGender(userId, gender, voiceDate);
            if (null == voice){
                throw new TanHuaException("暂时没有用户发送语音！");
            }
            //根据语音用户的id查询用户信息
            UserInfo userInfoVoice = userInfoApi.getUserInfo(voice.getUserId());
            //封装vo返回数据
            VoiceVo voiceVo = VoiceVo.init(userInfoVoice, voice);
            //设置接收语音剩余次数
            voiceVo.setRemainingTimes(receiveVoiceNum);
            receiveVoiceNum--;
            //将次数存入redis
            stringRedisTemplate.opsForHash().put(countKey, hashKey, receiveVoiceNum + "");

            //将已读语音的用户id和时间存入redis
            stringRedisTemplate.opsForSet().add(timeKey, voice.getCreated().toString());
            return voiceVo;
        }
        //没有次数返回提示信息
        throw new TanHuaException("免费次数不够了！快去开通VIP搜寻更多小哥哥小姐姐的语音吧!");
    }
}
